﻿using System.Collections.Generic;

public enum RedDotBindType
{
    None = 0,
    /// <summary>
    /// 红点在游戏内常驻
    /// </summary>
    Const,
    /// <summary>
    /// 一次性红点，在红点由True变False后移除绑定数据
    /// </summary>
    Once,
}

public class RedDotData
{
    public HashSet<RedDot> redDots = new HashSet<RedDot>();

    public RedDotType redDotType;
    public object subType;
    public object parentType;
    public RedDotBindType bingType;

    public bool isRed;
    public bool isDirty = true;
}

public class RedDotLayer
{
    public RedDotType RedDotType { get; set; }
    public IRedDotChecker RedDotChecker { get; set; }
    public RedDotLayer Parent { get; set; }
    public Dictionary<RedDotType, RedDotLayer> Childs { get; set; }

    public List<RedDotData> redDotDatas = new List<RedDotData>();

    public void Reset()
    {
        redDotDatas.Clear();
    }

    public bool IsRed(object subType, object parentType)
    {
        foreach (var item in redDotDatas)
        {
            if (IsEquals(item.subType, subType) && IsEquals(item.parentType, parentType))
            {
                if (item.isRed)
                    return true;
            }
        }

        if (IsChildRed(subType))
            return true;

        return false;
    }

    public bool TryGetData(object subType, object parentType, out RedDotData redDotData)
    {
        redDotData = null;
        foreach (var item in redDotDatas)
        {
            if (IsEquals(item.subType, subType) && IsEquals(item.parentType, parentType))
            {
                redDotData = item;
                return true;
            }
        }

        return false;
    }

    public static bool IsEquals(object left, object right)
    {
        // 都是null
        if (left == null && right == null)
            return true;

        // 只有一个是null
        if (left == null || right == null)
            return false;

        return left.Equals(right);
    }

    public void AddData(RedDotData redDotData)
    {
        redDotDatas.Add(redDotData);
    }

    public void RemoveData(RedDotData redDotData)
    {
        redDotDatas.Remove(redDotData);
    }

    private bool IsChildRed(object parentType)
    {
        if (Childs == null)
            return false;

        foreach (var childLayer in Childs.Values)
        {
            foreach (var childRedDotData in childLayer.redDotDatas)
            {
                if (IsEquals(childRedDotData.parentType, parentType))
                {
                    if (childRedDotData.isRed)
                        return true;

                    if (childLayer.IsChildRed(childRedDotData.subType))
                        return true;
                }
            }
        }

        return false;
    }

    public RedDotLayer AddChild(RedDotLayer child)
    {
        if (Childs == null)
            Childs = new Dictionary<RedDotType, RedDotLayer>();

        child.Parent = this;
        Childs.Add(child.RedDotType, child);
        return this;
    }
}